import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:get/get.dart';
import 'package:get/route_manager.dart';
import 'package:share_fit/app/controllers/base/base_controller.dart';
import 'package:share_fit/app/controllers/home/home_const.dart';
import 'package:share_fit/app/helper/db/ute_db_helper.dart';
import 'package:share_fit/app/helper/ext/tr_ext.dart';
import 'package:share_fit/app/models/home/menstrual_mode.dart';
import 'package:share_fit/app/routes/home_routes.dart';
import 'package:share_fit/app/tools/date_tool.dart';
import 'package:share_fit/app/tools/log_utils.dart';
import 'package:share_fit/app/ute/uteped_const.dart';
import 'package:share_fit/generated/locales.g.dart';

import 'state.dart';

class CycleCalendarSettingLogic extends BaseController {
  final CycleCalendarSettingState state = CycleCalendarSettingState();

  final String mSetMenstrualNotifyAbility = "setMenstrualNotifyAbility";
  final String mSetMenstrualCycleData = "setMenstrualCycleData";
  final String mSetAppMenstrualModifyTime = "setAppMenstrualModifyTime";
  final String mSetAppMenstrualCapability = "setAppMenstrualCapability";

  gotoCycleCalendarPage() {
    Future.delayed(Duration.zero, () => Get.offNamed(HomeRoutes.cycleCalendarPage));
  }

  onPopInvoked(bool didPop) {
    if (didPop) return;
    gotoCycleCalendarPage();
  }

  void setStartTime(DateTime? startTime) {
    if (startTime != null && startTime.compareTo(DateTool.truncateHMS()) > 0) {
      showToastWidget(
        Center(
          child: Text(LocaleKeys.cycle_calendar_no_after_today_text.ts, style: TextStyle(
              fontSize: 48.sp,
              color: Colors.white
          ),),
        ),
        context: Get.overlayContext!,
        isIgnoring: false,
        position: StyledToastPosition.bottom,
        duration: const Duration(seconds: 3),
        animation: StyledToastAnimation.none,
        reverseAnimation: StyledToastAnimation.none,
        animDuration: const Duration(milliseconds: 1000),
        curve: Curves.easeOut,
        reverseCurve: Curves.easeIn,
      );
      canStart();
      return;
    }

    state.startTime = DateTool.truncateHMS(now: startTime ?? DateTime.now());
    update([HomeConst.cycleCalendarSettingStartTime]);
    save(HomeConst.cycleCalendarSettingStartTime, state.startTime!.millisecondsSinceEpoch);
    Get.back();
    canStart();

    syncMenstrualCycleData();
  }

  void syncMenstrualNotifyAbility() async {
    Map map = {UTEPedConst.keyEnable: state.enableRemind};
    bRemoteReqAsync(mSetMenstrualNotifyAbility, {'map': map}).then((value) => logger2.d('setMenstrualNotifyAbility is $value'));
  }

  /// MENSTRUAL_CAPABILITY_QUERY = 1;  <br/>
  /// MENSTRUAL_CAPABILITY_UPDATE = 2;
  syncSetAppMenstrualCapability(int capability) {
    Map map = {};
    map['capability'] = capability;
    bRemoteReqAsync(mSetAppMenstrualCapability, {'map': map});
  }

  void updateMenstrualData(MenstrualModel menstrualData) {
    UteDbHelper.getDB().then((db) {
      db.menstrualDao.deleteAll();
      db.menstrualDao.insertOne(menstrualData);
    });
  }

  void onStartBtnClick() {
    showLoading();
    syncMenstrualCycleData();
    cancelLoading();
    gotoCycleCalendarPage();
  }

  /// 设置女性生理周期数据
  void syncMenstrualCycleData() {
    if (state.canSyncData) {
      MenstrualModel mm1 = getMenstrualData();
      MenstrualModel mm2 = getMenstrualData(startDate: DateTime.fromMillisecondsSinceEpoch(mm1.predictionStart!));
      MenstrualModel mm3 = getMenstrualData(startDate: DateTime.fromMillisecondsSinceEpoch(mm2.predictionStart!));
      List<MenstrualModel> mmList = [mm1, mm2, mm3];

      // 更新数据库记录
      updateMenstrualData(mm1);

      List data = mmList.map((e) => e.toMap()).toList();

      Map map = {
        'historyCycleSize': 2, // 设备所需的历史周期数,一般填1
        'futureCycleSize': 3, // 设备所需的预测未来周期数,一般填1
        'modifyTime': DateTool.getTimeInSeconds(DateTime.now()), // 设备所需要的周期数据中最新的修改时间点，格林尼治时间，单位：秒
        'manualMenstrualDays': mm1.menstruationDays, // 用户手动输入的经期长度
        'manualCycleDays': mm1.periodDays, // 用户手动输入的生理周期长度
        'menstrualDataList': data,
      };
      bRemoteReqAsync(mSetMenstrualCycleData, {'map': map}).then((success) {
        logger2.d('mSetMenstrualCycleData $success');
        // gotoCycleCalendarPage();
      });
    }
  }

  @override
  String getRemotePath() {
    return UTEPedConst.pathMenstrual;
  }

  @override
  String getStoragePath() {
    return UTEPedConst.pathMenstrual;
  }

  @override
  void initState() {
    state.enableRemind = read(HomeConst.cycleCalendarEnableRemind, defaultValue: false);
    update([HomeConst.cycleCalendarEnableRemind]);

    state.durationIndex = read(HomeConst.cycleCalendarDurationIndex, defaultValue: 3);
    update([HomeConst.cycleCalendarDurationIndex]);

    state.periodIndex = read(HomeConst.cycleCalendarSelectedPeriodDayIndex, defaultValue: 0);
    update([HomeConst.cycleCalendarSelectedPeriodDayIndex]);

    int? startTimestamp = read(HomeConst.cycleCalendarSettingStartTime, defaultValue: null);
    state.startTime = startTimestamp == null ? null : DateTime.fromMillisecondsSinceEpoch(startTimestamp);
    update([HomeConst.cycleCalendarSettingStartTime]);

    if (state.durationList.isEmpty && state.periodDays.isEmpty) {
      initSelectionItem();
    }

    canStart();
  }

  @override
  void onRemoteEvent(event, method) {
    // TODO: implement onRemoteEvent
  }

  void setEnableRemind(bool value) {
    state.enableRemind = value;
    save(HomeConst.cycleCalendarEnableRemind, value);
    update([HomeConst.cycleCalendarEnableRemind]);

    syncMenstrualNotifyAbility();
  }

  durationChange(val) {
    state.durationIndex = val;
    canStart();
  }

  void setDuration() {
    save(HomeConst.cycleCalendarDurationIndex, state.durationIndex);
    save(HomeConst.cycleCalendarDurationDays, state.durationList[state.durationIndex]['label']);
    update([HomeConst.cycleCalendarDurationIndex]);
    Get.back();

    syncMenstrualCycleData();
  }

  periodChange(val) {
    state.periodIndex = val;
    canStart();
  }

  canStart() {
    state.canSyncData = state.startTime != null && DateTool.differentInDays(state.startTime!, DateTime.now()) <= 0;
    update(['start_button']);
  }

  void setPeriod() {
    save(HomeConst.cycleCalendarSelectedPeriodDayIndex, state.periodIndex);
    save(HomeConst.cycleCalendarSelectedDays, state.periodDays[state.periodIndex]);
    update([HomeConst.cycleCalendarSelectedDays]);
    Get.back();

    syncMenstrualCycleData();
  }

  void initSelectionItem() {
    state.periodDays.clear();
    for (var i = 15; i <= 40; i++) {
      if (i == 28) {
        //   state.periodIndex = i - 15;
        state.periodIndex = read(HomeConst.cycleCalendarSelectedPeriodDayIndex, defaultValue: i - 15);
      }
      state.periodDays.add({'label': i, 'value': i - 15});
    }

    state.durationList.clear();
    for (var i = 3; i <= 8; i++) {
      if (i == 5) {
        // state.durationIndex = i - 3;
        state.durationIndex = read(HomeConst.cycleCalendarDurationIndex, defaultValue: i - 3);
      }
      state.durationList.add({'label': i, 'value': i - 3});
    }
  }

  MenstrualModel getMenstrualData({DateTime? startDate}) {
    // 周期天数
    int cycleDays = state.periodDays[state.periodIndex]['label']!;
    // 经期天数
    int menstrualDays = state.durationList[state.durationIndex]['label']!;
    // 经期开始日期
    DateTime mStartDate = startDate ?? state.startTime!;

    MenstrualModel model = MenstrualModel(true);
    model.newModel(startDate: mStartDate, inPeriodDays: cycleDays, inMenstruationDays: menstrualDays, inAddress: getAddress());
    return model;
    //
    //
    // // 经期开始日期
    // DateTime mStartDate = startDate ?? state.startTime!;
    // // 经期结束日期
    // DateTime mEndTime = DateTool.offsetDays(mStartDate, menstrualDays - 1);
    // // 预测经期开始时间，上次经期开始日 + 经期周期
    // DateTime predictionStartDate = DateTool.offsetDays(mStartDate, cycleDays);
    // // 预测经期结束时间
    // DateTime predictionEnd = DateTool.offsetDays(predictionStartDate, menstrualDays - 1);
    //
    // // 排卵日，下次月经前的第14天
    // DateTime ovDate = DateTool.offsetDays(predictionStartDate, -14);
    // // 易孕开始日期，排卵日前5天
    // DateTime epStartTime = DateTool.offsetDays(ovDate, -5);
    // // 易孕结束日期，排卵日后4天
    // DateTime epEndTime = DateTool.offsetDays(ovDate, 4);
    //
    // return MenstrualModel(
    //   true,
    //   periodDays: cycleDays,
    //   menstruationDays: menstrualDays,
    //   menstruationStart: mStartDate.millisecondsSinceEpoch,
    //   menstruationEnd: mEndTime.millisecondsSinceEpoch,
    //   predictionStart: predictionStartDate.millisecondsSinceEpoch,
    //   predictionEnd: predictionEnd.millisecondsSinceEpoch,
    //   easyPregnancyStart: epStartTime.millisecondsSinceEpoch,
    //   easyPregnancyEnd: epEndTime.millisecondsSinceEpoch,
    //   ovulationDate: ovDate.millisecondsSinceEpoch,
    //   dateCreated: DateTime.now().millisecondsSinceEpoch,
    //   dateModified: DateTime.now().millisecondsSinceEpoch,
    //   address: getAddress(),
    // );
  }
}
